package top.itaso.lib.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.NumberPicker;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;

/**
 * @Description: 年月日 时分 选择器
 * 1.NumberPicker 当设置了 setDisplayedValues 后，如果在设置 setFormatter ，则 Formatter 会失效，即不会有回调
 * 2.monthPicker 导入 DisplayedValues 用于 Picker 上的文案显示，月份结果使用 getValue 并进行补 0 匹配
 * 3.dayPicker 整型 补 0 匹配
 * 4.hourPicker 不导入 DisplayedValues 进行直接 Formatter 显示文案，并根据 getValue 值取出 定义的 HOUR_DISPLAY 结果用于小时
 * 5.minutePicker 设置循环取值
 * @Author itsdf07
 * @E-Mail 923255742@qq.com
 * @Gitee https://gitee.com/itsdf07
 * @Date 2022/1/20
 */
public class WidgetDateTimePicker extends LinearLayout implements
        NumberPicker.OnValueChangeListener,
        NumberPicker.OnScrollListener {
    private final String TAG = this.getClass().getSimpleName();

    //    private final String[] MONTH_DISPLAY = {"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"};
    private final String[] MONTH_DISPLAY = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
    private final String[] HOUR_DISPLAY = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"};
    private NumberPicker yearPicker;
    private NumberPicker monthPicker;
    private NumberPicker dayPicker;
    private NumberPicker hourPicker;
    private NumberPicker minutePicker;

    private Calendar calendar;

    @Override
    public void onScrollStateChange(NumberPicker view, int scrollState) {
        switch (scrollState) {
            case NumberPicker.OnScrollListener.SCROLL_STATE_FLING://手离开之后还在滑动
                Log.v(TAG, "onScrollStateChange: >>>>>>惯性滑动中，scrollState:" + scrollState);
                break;
            case NumberPicker.OnScrollListener.SCROLL_STATE_IDLE://不滑动了
                Log.d(TAG, "onScrollStateChange: >>>>>>滑动结束，scrollState:" + scrollState);
                break;
            case NumberPicker.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL://触摸滑动中
                Log.d(TAG, "onScrollStateChange: >>>>>>触摸滑动中，scrollState:" + scrollState);
                break;
            default:
                Log.d(TAG, "onScrollStateChange: >>>>>>异常态，scrollState:" + scrollState);
                break;
        }
    }


    public interface IDateCallback {
        /**
         * @param dateValue yyyy-MM-dd HH:mm
         */
        void onConfirm(String dateValue);
    }


    public WidgetDateTimePicker(@NonNull Context context) {
        this(context, null);
    }

    public WidgetDateTimePicker(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public WidgetDateTimePicker(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        calendar = Calendar.getInstance();
        initView();
    }

    @Override
    public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
        Log.v(TAG, "onValueChange: >>>>>>oldVal=" + oldVal + ",newVal=" + newVal + ",picker=" + picker);
        String dateStr = String.format(Locale.CHINA, "%d-%d", yearPicker.getValue(), monthPicker.getValue());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM", Locale.CHINA);
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTime(simpleDateFormat.parse(dateStr));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int dateValue = dayPicker.getValue();
        int maxValue = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        dayPicker.setMaxValue(maxValue);
        //重设日期值，防止月份变动时超过最大值
        dayPicker.setValue(Math.min(dateValue, maxValue));
    }

    public void onConfirm(IDateCallback dateCallback) {
        if (dateCallback != null) {
            String result = String.format(Locale.CHINA, "%s-%s-%s %s:%s",
                    yearPicker.getValue(),
                    formatter0(monthPicker.getValue() + 1),
                    dayPicker.getValue(),
                    HOUR_DISPLAY[hourPicker.getValue()],
                    formatter0(minutePicker.getValue()));
            Log.d(TAG, "onConfirm: >>>>>>result=" + result);
            dateCallback.onConfirm(result);
        }
    }


    private void initView() {
        inflate(getContext(), R.layout.layout_datetime_picker, this);

        yearPicker = findViewById(R.id.np_year);
        monthPicker = findViewById(R.id.np_month);
        dayPicker = findViewById(R.id.np_day);
        hourPicker = findViewById(R.id.np_hour);
        minutePicker = findViewById(R.id.np_minute);

        //限制年份范围为前后10年
        int yearNow = calendar.get(Calendar.YEAR);
        yearPicker.setMinValue(yearNow - 10);
        yearPicker.setMaxValue(yearNow + 10);
        yearPicker.setValue(yearNow);
        yearPicker.setWrapSelectorWheel(true);  //true-允许选择器循环（默认），false-关闭选择器循环


        //设置月份范围为0~11，目的为了与MONTH_DISPLAY索引相对应
        monthPicker.setDisplayedValues(MONTH_DISPLAY);//设置了 setDisplayedValues 后，如果在设置 setFormatter ，则 Formatter 会失效，即不会有回调
        monthPicker.setMinValue(0);
        monthPicker.setMaxValue(MONTH_DISPLAY.length - 1);
        monthPicker.setValue(calendar.get(Calendar.MONTH));
        monthPicker.setWrapSelectorWheel(true);


        //日期限制存在变化，需要根据当月最大天数来调整
        dayPicker.setMinValue(1);
        dayPicker.setMaxValue(calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        dayPicker.setValue(calendar.get(Calendar.DATE));
        dayPicker.setWrapSelectorWheel(true);


        //24小时制，限制小时数为0~23
        hourPicker.setMinValue(0);
        hourPicker.setMaxValue(HOUR_DISPLAY.length - 1);
        hourPicker.setValue(calendar.get(Calendar.HOUR_OF_DAY) - 1);
        hourPicker.setWrapSelectorWheel(true);


        //限制分钟数为0~59
        minutePicker.setMinValue(0);
        minutePicker.setMaxValue(59);
        minutePicker.setValue(calendar.get(Calendar.MINUTE));
        minutePicker.setWrapSelectorWheel(true);


        //监听滑动事件
        yearPicker.setOnScrollListener(this);

        //匹配选择器内容，如在 1 前面补 0 成为 01
        dayPicker.setFormatter(formatter0);
        hourPicker.setFormatter(formatterHourDisplay2Picker);
        minutePicker.setFormatter(formatter0);

        //为年份和月份设置监听
        yearPicker.setOnValueChangedListener(this);
        monthPicker.setOnValueChangedListener(this);
    }


    /**
     * 设置 小时 Picker 上的文案显示：从 HOUR_DISPLAY 中进行提取显示
     */
    private NumberPicker.Formatter formatterHourDisplay2Picker = new NumberPicker.Formatter() {
        @Override
        public String format(int value) {
            String displayText = HOUR_DISPLAY[value];
            Log.v(TAG, "formatterHourDisplay2Picker format: >>>>>>设置Picker上小时的显示文案，value:" + value + ",displayText:" + displayText);
            return displayText;
        }
    };

    /**
     * 个位数值时的十位数补0
     */
    private NumberPicker.Formatter formatter0 = new NumberPicker.Formatter() {
        @Override
        public String format(int value) {
            Log.v(TAG, "formatter0 format: >>>>>>value:" + value);
            return formatter0(value);
        }
    };

    /**
     * 对个位数值时的十位数补0
     *
     * @param value 1
     * @return 01
     */
    private String formatter0(int value) {
        DecimalFormat decimalFormat = new DecimalFormat();
        decimalFormat.applyPattern("##");
        decimalFormat.setMinimumIntegerDigits(2);
        return decimalFormat.format(value);
    }


}
